﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SqlClient;
using BlueLotus7.Eden.Service.Properties;
using BlueLotus7.ArchiveSystem.Common;

namespace BlueLotus7.Eden.Service.BusinessLayer
{
    public class StatusDataAdapter : BaseDataAdapter
    {
        #region Columns

        #endregion

        public StatusDataAdapter()
            : base()
        {
        }

        #region Status

        public void ReportStatus(Guid domainScopeKey, Guid domainScopeUserKey, int status)
        {
            const string spName = "sp_ReportStatus";

            List<SqlParameter> parameters = new List<SqlParameter>();
            SqlParameter parameter;

            parameter = GenerateSqlParameter(GenerateParameterByColumnName(Prefix_DomainScope + Column_Key), domainScopeKey);
            parameters.Add(parameter);

            parameter = GenerateSqlParameter(GenerateParameterByColumnName(Prefix_DomainScopeUser + Column_Key), domainScopeUserKey);
            parameters.Add(parameter);

            parameter = GenerateSqlParameter(GenerateParameterByColumnName(Column_Status), status);
            parameters.Add(parameter);

            parameter = GenerateSqlParameter(GenerateParameterByColumnName(Column_Stamp), DateTime.Now);
            parameters.Add(parameter);

            var databaseOperator = new DatabaseOperator(this.CreateSqlConnection());
            try
            {
                databaseOperator.ExecuteNonQuery(spName, parameters);
            }
            catch
            {
                throw;
            }
            finally
            {
                databaseOperator.Dispose();
            }
        }

        public void MergeStatus(Guid domainScopeUserKey, int status, Guid startGuid, Guid endGuid)
        {
            const string spName = "sp_MergeStatus";

            List<SqlParameter> parameters = new List<SqlParameter>();
            SqlParameter parameter;

            parameter = GenerateSqlParameter(GenerateParameterByColumnName(Prefix_DomainScopeUser + Column_Key), domainScopeUserKey);
            parameters.Add(parameter);

            parameter = GenerateSqlParameter(GenerateParameterByColumnName(Column_StartGuid), startGuid);
            parameters.Add(parameter);

            parameter = GenerateSqlParameter(GenerateParameterByColumnName(Column_EndGuid), endGuid);
            parameters.Add(parameter);

            parameter = GenerateSqlParameter(GenerateParameterByColumnName(Column_Status), status);
            parameters.Add(parameter);

            var databaseOperator = new DatabaseOperator(this.CreateSqlConnection());
            try
            {
                databaseOperator.ExecuteNonQuery(spName, parameters);
            }
            catch
            {
                throw;
            }
            finally
            {
                databaseOperator.Dispose();
            }
        }

        public List<TargetStatus> QueryStatus(Guid? domainScopeKey, Guid? domainScopeUserKey, DateTime startTime, DateTime endTime)
        {
            const string spName = "sp_QueryStatus";
            List<TargetStatus> result = new List<TargetStatus>();

            List<SqlParameter> parameters = new List<SqlParameter>();
            SqlParameter parameter;

            parameter = GenerateSqlParameter(GenerateParameterByColumnName(Prefix_DomainScope + Column_Key), domainScopeKey);
            parameters.Add(parameter);

            parameter = GenerateSqlParameter(GenerateParameterByColumnName(Prefix_DomainScopeUser + Column_Key), domainScopeUserKey);
            parameters.Add(parameter);

            parameter = GenerateSqlParameter(GenerateParameterByColumnName(Column_StartStamp), startTime);
            parameters.Add(parameter);

            parameter = GenerateSqlParameter(GenerateParameterByColumnName(Column_EndStamp), endTime);
            parameters.Add(parameter);

            parameter = GenerateSqlParameter(GenerateParameterByColumnName(Column_OrderDESC), 1);
            parameters.Add(parameter);

            SqlDataReader reader = null;
            var databaseOperator = new DatabaseOperator(this.CreateSqlConnection());

            try
            {
                reader = databaseOperator.ExecuteReader(spName, parameters);
                result = ReadTargetStatus(reader);
            }
            catch
            {
                throw;
            }
            finally
            {
                if (reader != null)
                {
                    reader.Close();
                    reader.Dispose();
                }
                databaseOperator.Dispose();
            }

            return result;
        }

        public TargetStatus GetLatestStatus(Guid domainScopeKey, Guid domainScopeUserKey)
        {
            const string spName = "sp_GetLastStatus";
            List<TargetStatus> result = new List<TargetStatus>();

            List<SqlParameter> parameters = new List<SqlParameter>();
            SqlParameter parameter;

            parameter = GenerateSqlParameter(GenerateParameterByColumnName(Prefix_DomainScope + Column_Key), domainScopeKey);
            parameters.Add(parameter);

            parameter = GenerateSqlParameter(GenerateParameterByColumnName(Prefix_DomainScopeUser + Column_Key), domainScopeUserKey);
            parameters.Add(parameter);

            SqlDataReader reader = null;
            var databaseOperator = new DatabaseOperator(this.CreateSqlConnection());

            try
            {
                reader = databaseOperator.ExecuteReader(spName, parameters);
                result = ReadTargetStatus(reader);
            }
            catch
            {
                throw;
            }
            finally
            {
                if (reader != null)
                {
                    reader.Close();
                    reader.Dispose();
                }
                databaseOperator.Dispose();

            }

            return result.Count > 0 ? result[0] : null;
        }

        public List<DomainScopeUser> GetDomainScopeUsersForMonitor(Guid domainScopeKey)
        {
            const string spName = "sp_GetDomainScopeUsersForMonitor";
            List<DomainScopeUser> result = new List<DomainScopeUser>();

            List<SqlParameter> parameters = new List<SqlParameter>();
            SqlParameter parameter;

            parameter = GenerateSqlParameter(GenerateParameterByColumnName(Column_DomainScopeKey), domainScopeKey);
            parameters.Add(parameter);

            SqlDataReader reader = null;
            var databaseOperator = new DatabaseOperator(this.CreateSqlConnection());
            try
            {
                reader = databaseOperator.ExecuteReader(spName, parameters);
                result = ReadDomainScopeUsers(reader, true);
            }
            catch
            {
                throw;
            }
            finally
            {
                if (reader != null)
                {
                    reader.Close();
                    reader.Dispose();
                }
                databaseOperator.Dispose();

            }

            return result;
        }


        public List<DomainScopeUserFullInfo> GetDomainScopeUsersWithStatus(Guid? domainScopeKey)
        {
            const string spName = "sp_GetDomainScopeUsersWithStatus";
            List<DomainScopeUserFullInfo> result = new List<DomainScopeUserFullInfo>();

            List<SqlParameter> parameters = new List<SqlParameter>();
            SqlParameter parameter;

            parameter = GenerateSqlParameter(GenerateParameterByColumnName(Prefix_DomainScope + Column_Key), domainScopeKey);
            parameters.Add(parameter);

            SqlDataReader reader = null;
            var databaseOperator = new DatabaseOperator(this.CreateSqlConnection());

            try
            {
                reader = databaseOperator.ExecuteReader(spName, parameters);
                result = ReadDomainScopeUserFullInfo(reader);
            }
            catch
            {
                throw;
            }
            finally
            {
                if (reader != null)
                {
                    reader.Close();
                    reader.Dispose();
                }
                databaseOperator.Dispose();

            }

            return result;
        }

        #endregion

        #region Readers

        protected static List<TargetStatus> ReadTargetStatus(SqlDataReader reader)
        {
            List<TargetStatus> result = new List<TargetStatus>();

            if (reader != null)
            {
                while (reader.Read())
                {
                    //[Key],[DomainScopeKey],[DomainScopeUserKey],[Status],[StartStamp],[EndStamp]
                    TargetStatus obj = new TargetStatus();

                    obj.Key = (Guid)reader[Column_Key];
                    obj.Status = (int)reader[Column_Status];
                    obj.StartStamp = (DateTime)(reader[Column_StartStamp]);
                    obj.EndStamp = (DateTime)(reader[Column_EndStamp]);
                    obj.DomainScopeUserKey = (Guid)reader[Prefix_DomainScopeUser + Column_Key];
                    obj.DomainScopeKey = (Guid)reader[Prefix_DomainScope + Column_Key];

                    result.Add(obj);
                }
            }

            return result;
        }

        protected static List<DomainScopeUserFullInfo> ReadDomainScopeUserFullInfo(SqlDataReader reader)
        {
            List<DomainScopeUserFullInfo> result = new List<DomainScopeUserFullInfo>();

            if (reader != null)
            {
                while (reader.Read())
                {
                    //[DomainScopeUserKey],[DomainScopeKey],[PersonKey],[Description],[ThirdPartyIdentity],[MonitorStatus],[LastUpdatedStamp],[DomainScope],[Status],[StartStamp],[EndStamp] 
                    DomainScopeUserFullInfo obj = new DomainScopeUserFullInfo();
                    obj.Key = (Guid)reader[Column_DomainScopeUserKey];
                    obj.DomainScope = new DomainScope { Key = (Guid)reader[Column_DomainScopeKey], Name = (string)reader[Prefix_DomainScope + Column_Name] };
                    obj.Description = GetStringValue(reader[Column_Description]);
                    obj.ThirdPartyIdentity = (string)reader[Column_ThirdPartyIdentity];
                    obj.MonitorStatus = (bool)reader[Column_MonitorStatus];
                    obj.CreatedStamp = (DateTime)reader[Column_CreatedStamp];
                    obj.LastUpdatedStamp = (DateTime)reader[Column_LastUpdatedStamp];
                    obj.Status = new TargetStatus { Status = (int)reader[Column_Status], StartStamp = (DateTime)(reader[Column_StartStamp]), EndStamp = (DateTime)(reader[Column_EndStamp]) };

                    result.Add(obj);
                }
            }

            return result;
        }



        #endregion
    }
}
